package org.gntc.prayer.myprayer;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.gntc.prayer.R;
import org.gntc.prayer.common.CategoryInfo;
import org.gntc.prayer.common.PrayerInfo;
import org.gntc.prayer.db.PrayerDBMngr;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TimePicker;
import android.widget.Toast;

public class PrayerEditActivity extends Activity
{
	/** Called when the activity is first created. */
	
	private PrayerDBMngr m_PrayerDBMngr;
	private Map<Integer, CategoryInfo> m_mapCategory;
	private int 			m_nSelCategoryIdx;
	private boolean 	m_bSelCateFlag;
	private int			m_nHour;
	private int			m_nMinute;
	private boolean		m_bEditMode;
	private int			m_nPrayerID;
	private int			m_nSavedCateID;
	private EditText 		m_etCategory;
	private Button 		m_btnSelectCategory;
	private EditText 		m_etPrayer;
	private CheckBox 	m_ckAlarm;
	private Button 		m_btnAlarmTime;
	private Button		m_btnSaveContinue;
	
	/**
	 * Select category button click listener
	 */
	private View.OnClickListener m_onClickListener_btnSelectCategory = new Button.OnClickListener()
	{
		public void onClick(View v)
		{
			showSelectCategoryDlg();
		}
	};
	
	/**
	 * Category 선택 click listener
	 */
	private DialogInterface.OnClickListener m_onClickListener_selCate = new DialogInterface.OnClickListener()
	{
		public void onClick(DialogInterface dialog, int which)
		{
			setCategoryName(which);
			dialog.cancel();
		}
	};
	
	/**
	 * Category 이름 변경 listener
	 */
	private TextWatcher m_textChangedListener_etCate = new TextWatcher()
	{
		public void afterTextChanged(Editable s)
		{
			if (!m_bSelCateFlag)
			{
				// Category 팝업 창에서 선택한 경우가 아닐 때만 Category idx 변경
				m_nSelCategoryIdx = -1;
			}
			
			m_bSelCateFlag = false;
		}

		public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
		public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
	};
	
	/**
	 * Alarm 체크 박스 표시 Click listener
	 */
	private View.OnClickListener m_onClickListener_ckAlarm = new Button.OnClickListener()
	{
		public void onClick(View v)
		{
			setAlarmTimeButton();
		}
	};
	
	/**
	 * Alarm time 버튼 Click listener
	 */
	private View.OnClickListener m_onClickListener_btnAlarmTime = new Button.OnClickListener()
	{
		public void onClick(View v)
		{
			// TimePicker 표시
			showAlarmTimePicker();
		}
	};
	
	/**
	 * Alarm 시간 설정 listener
	 */
	private TimePickerDialog.OnTimeSetListener m_onTimeSetListener = new TimePickerDialog.OnTimeSetListener()
	{
		public void onTimeSet(TimePicker view, int hourOfDay, int minute)
		{
			m_nHour = hourOfDay;
			m_nMinute = minute;
			
			setAlarmTime();
		}
	};
	
	/**
	 * Edit 취소 시 팝업 창에서 Yes 버튼 Click listener
	 */
	private DialogInterface.OnClickListener m_onClickListener_btnYes = new DialogInterface.OnClickListener()
	{
		public void onClick(DialogInterface dialog, int which)
		{
			// Yes 를 누른 경우 현재 Activity를 종료
			finish();
		}
	};
	
	/**
	 * Save continue 버튼 Click listener
	 */
	private View.OnClickListener m_onClickListener_btnSaveContinue = new Button.OnClickListener()
	{
		public void onClick(View v)
		{
			// Prayer 계속 저장
			saveContinuePrayer();
		}
	};
	
	/**
	 * onCreate
	 */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.prayer_edit);
	    
	    // 멤버 변수 초기화
	    m_mapCategory = null;
	    m_nSelCategoryIdx = -1;
		m_bSelCateFlag = false;
		m_nHour = 0;
		m_nMinute = 0;
		m_nSavedCateID = -1;
		
	    // Title bar 설정
		/*
	    ViewGroup v = (ViewGroup) findViewById(R.id.edit_main_layout).getParent().getParent();		// get Title bar
	    v = (ViewGroup) v.getChildAt(0);
	    
	    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	    View v1 = vi.inflate(R.layout.title_bar_edit, null);
	    
	    v.addView(v1, 1);
	    */
	    
	    // 수정 모드인지 확인
	    m_bEditMode = false;
	    
	    Intent intent = getIntent();
	    Bundle extra = intent.getExtras();
	    
	    if (extra != null)
	    {
	    	m_bEditMode = extra.getBoolean("edit_mode");
	    	
	    	if (m_bEditMode)
	    	{
	    		m_nPrayerID = extra.getInt("id");
	    	}
	    }
	    
	    // 컨트롤 설정
	    /*
	    m_btnDone = (Button) findViewById(R.id.btn_edit_done);
	    m_btnDone.setOnClickListener(m_onClickListener_btnDone);
	    
	    m_btnCancel = (Button)findViewById(R.id.btn_edit_cancel);
	    m_btnCancel.setOnClickListener(m_onClickListener_btnCancel);
	    */
	    
	    m_etCategory = (EditText) findViewById(R.id.edit_category);
	    m_etCategory.addTextChangedListener(m_textChangedListener_etCate);
	    
	    m_btnSelectCategory = (Button) findViewById(R.id.btn_select_category);
	    m_btnSelectCategory.setOnClickListener(m_onClickListener_btnSelectCategory);
	    
	    m_etPrayer = (EditText) findViewById(R.id.edit_prayer);
	    
	    m_ckAlarm = (CheckBox) findViewById(R.id.ck_alarm);
	    m_ckAlarm.setOnClickListener(m_onClickListener_ckAlarm);
	    
	    m_btnAlarmTime = (Button) findViewById(R.id.btn_alarm_time);
	    m_btnAlarmTime.setOnClickListener(m_onClickListener_btnAlarmTime);
	    
	    if (m_bEditMode)
	    {
	    	// 수정 모드
	    	LinearLayout layout = (LinearLayout) findViewById(R.id.save_continue_layout);
	    	layout.setVisibility(View.INVISIBLE);
	    }
	    else
	    {
	    	// 신규 추가 모드
	    	m_btnSaveContinue = (Button) findViewById(R.id.btn_save_continue);
	    	m_btnSaveContinue.setOnClickListener(m_onClickListener_btnSaveContinue);
	    }
	    
	    // DB 초기화 및 Open
	    initDB();
	    
	    // Alarm 
	    setAlarmTimeButton();
	}
	
	/**
	 * onResume
	 */
	@Override
	public void onResume()
	{
		super.onResume();
		
		if (m_bEditMode)
		{
			// Prayer 정보 구하기
			getPrayerInfo();
		}
		
		// Category 초기화
	    getCategoryName();
	}
	
	/**
	 * Menu
	 */
	@Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
    	getMenuInflater().inflate(R.menu.prayer_edit_menu, menu);
    	return true;
    }
	
	/**
	 * Menu selected
	 */
	@Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
    	switch( item.getItemId() )
    	{
    	case R.id.prayer_edit_btn_save :
    		{
    			boolean bVal = false;
    			
				if (m_bEditMode)
				{
					// Edit Prayer
					editPrayer();
					finish();
				}
				else
				{
					// Save Prayer
					bVal = savePrayer();
				}
				
				if (bVal)
				{
					Toast.makeText(PrayerEditActivity.this, R.string.prayer_saved, Toast.LENGTH_SHORT).show();
					finish();
				}
    		}
    		break;
    		
    	case R.id.prayer_edit_btn_cancel :
    		finishActivity();
    		break;
    		
    	default :
    		return false;
    	}
    	
    	return true;
    }
	
	/**
	 * Prayer 정보 구하기
	 */
	private PrayerInfo getPrayerInfo()
	{
		PrayerInfo pi = m_PrayerDBMngr.getPrayerInfo(m_nPrayerID);
		
		// Category ID
		m_nSavedCateID = pi.getM_nCategoryID();
		
		// Prayer
		m_etPrayer.setText(pi.getM_strPrayer());
		
		// Alarm
		if (pi.getM_bIsSetAlarm())
		{
			// Alarm check
			m_ckAlarm.setChecked(true);
			setAlarmTimeButton();
			
			// Alarm time
			m_btnAlarmTime.setText(pi.getM_strAlarmTime());
		}
		else
		{
			// Alarm check
			m_ckAlarm.setChecked(false);
			setAlarmTimeButton();
		}
		
		return pi;
	}

	/**
	 * Alarm time 설정
	 */
	private void setAlarmTimeButton()
	{
		// Alarm 버튼에 현재 시간 표시
		Calendar cal = Calendar.getInstance();
		
		m_nHour = cal.get(Calendar.HOUR_OF_DAY);
		m_nMinute = cal.get(Calendar.MINUTE);
		
		String strAlarmTime = "";
		int nHour = m_nHour;
		
		if (m_nHour > 12)
		{
			strAlarmTime = "PM ";
			nHour = nHour - 12;
		}
		else
		{
			strAlarmTime = "AM ";
		}
		
		strAlarmTime += nHour + " : " + m_nMinute;
		
		m_btnAlarmTime.setText(strAlarmTime);
		
		// 체크에 따라 활성화 여부
		if (m_ckAlarm.isChecked())
		{
			// Alarm 체크 되어 있으면 Enable
			m_btnAlarmTime.setEnabled(true);
		}
		else
		{
			// Alarm 체크 되어 있지 않으면 Disable
			m_btnAlarmTime.setEnabled(false);
		}
	}
	
	/**
	 * Category 선택 dialog 표시
	 */
	private void showSelectCategoryDlg()
	{
		// Category name
		int nCnt = m_mapCategory.size();
		
		String strCateName[] = new String[nCnt];
		
		for (int i = 0; i < nCnt; i++)
		{
			strCateName[i] = m_mapCategory.get(i).getM_strCategoryName();
		}
		
		// Category 선택 팝업 창
		AlertDialog.Builder ab = new AlertDialog.Builder(this);
		ab.setTitle(R.string.category)
		.setSingleChoiceItems(strCateName, m_nSelCategoryIdx, m_onClickListener_selCate)
		.setNegativeButton(R.string.cancel, null);
		
		ab.show();
	}
	
	/**
	 * Alarm time picker 표시
	 */
	private void showAlarmTimePicker()
	{
		TimePickerDialog tpd = new TimePickerDialog(this, m_onTimeSetListener, m_nHour, m_nMinute, false);
		tpd.show();
	}
	
	/**
	 * 선택한 Category 설정 
	 * @param nCateIdx
	 */
	private void setCategoryName(int nCateIdx)
	{
		m_bSelCateFlag = true;
		
		// Category Idx 설정
		m_nSelCategoryIdx = nCateIdx;
		
		// Category 이름 표시
		m_etCategory.setText(m_mapCategory.get(nCateIdx).getM_strCategoryName());
		
		// 마지막으로 커서 이동
		m_etCategory.setSelection(m_etCategory.length());
	}
	
	/**
	 * Alarm 시간 표시
	 */
	private void setAlarmTime()
	{
		String strAlarmTime;
		int nHour = m_nHour;
		int nMinute = m_nMinute;
		
		if (nHour > 12)
		{
			nHour = nHour - 12;
			strAlarmTime = "PM ";
		}
		else
		{
			strAlarmTime = "AM ";
		}
		
		strAlarmTime += nHour + " : " + nMinute;
				
		m_btnAlarmTime.setText(strAlarmTime);
	}
	
	/**
	 * Activity 종료
	 */
	private void finishActivity()
	{
		if (m_etCategory.getText().toString().length() == 0 && 
			m_etPrayer.getText().toString().length() == 0)
		{
			// 입력 사항이 없으면 바로 Activity 종료
			finish();
		}
		else
		{
			// 입력 사항이 있으면 팝업 창 표시
			AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
			
			alt_bld
			.setTitle(R.string.discard_changes)
			.setMessage(R.string.discard_changes_q).setCancelable(false)
			.setPositiveButton(R.string.yes, m_onClickListener_btnYes)
	        .setNegativeButton(R.string.no, null);
			
			AlertDialog altDlg = alt_bld.create();
			altDlg.setCancelable(true);
			altDlg.show();
		}
	}
	
	/**
	 * onDestroy
	 */
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		
		// DB Close
		m_PrayerDBMngr.close();
	}
	
	/**
	 * DB 초기화
	 */
	private void initDB()
	{
		m_PrayerDBMngr = new PrayerDBMngr(this);
		
		try
		{
			m_PrayerDBMngr.open();
		}
		catch (SQLiteException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Category name 가져오기
	 */
	private void getCategoryName()
	{
		if (m_mapCategory == null)
		{
			// Map 생성
			m_mapCategory = new HashMap<Integer, CategoryInfo>();
		}
		else
		{
			// Map 초기화
			m_mapCategory.clear();
		}
		
		// DB에서 Category 이름 구하기
		Cursor c = m_PrayerDBMngr.getAllCategoryName();
		
		int nCnt = c.getCount();
		c.moveToFirst();
		
		for (int i = 0; i < nCnt; i++)
		{
			int nId = c.getInt(0);
			String strName = c.getString(1);
			String strDate = c.getString(2);
			
			CategoryInfo ci = new CategoryInfo(nId, strName, strDate);
			
			m_mapCategory.put(i, ci);
			
			if (m_nSavedCateID == nId)
			{
				m_etCategory.setText(strName);
				m_etCategory.setSelection(m_etCategory.length());		// 커서를 마지막으로 이동
				
				m_nSelCategoryIdx = i;
			}
			
			c.moveToNext();
		}
		
		c.close();
	}
	
	/**
	 * Prayer 저장
	 * @return
	 */
	private boolean savePrayer()
	{
		boolean bRet 		 = false;
		int 	nCateID 	 = 0;
		String 	strAlarmTime = "";
		
		// Category ID
		if (m_nSelCategoryIdx == -1)
		{
			// Category 이름 검사
			if (m_etCategory.length() == 0)
			{
				Toast.makeText(PrayerEditActivity.this, R.string.add_category, Toast.LENGTH_SHORT).show();
				m_etCategory.requestFocus();
				return false;
			}
			else
			{
				// 같은 이름의 Category 가 있는지 검사
				nCateID = m_PrayerDBMngr.checkCategoryName(m_etCategory.getText().toString());
				
				if (nCateID == -1)
				{
					// 신규 category 저장
					long lRowID = m_PrayerDBMngr.insertCategory(m_etCategory.getText().toString());
					
					if (lRowID == -1)
					{
						// Error
						Toast.makeText(PrayerEditActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
						finish();
						return false;
					}
					else
					{
						m_nSelCategoryIdx = (int)lRowID;
						nCateID = m_nSelCategoryIdx;
					}
				}
			}
		}
		else
		{
			nCateID = m_mapCategory.get(m_nSelCategoryIdx).getM_nCategoryID();
		}
		
		// Prayer
		if (m_etPrayer.length() == 0)
		{
			Toast.makeText(PrayerEditActivity.this, R.string.add_prayer, Toast.LENGTH_SHORT).show();
			m_etPrayer.requestFocus();
			return false;
		}
		
		// Alarm
		if (m_ckAlarm.isChecked())
		{
			strAlarmTime = m_btnAlarmTime.getText().toString();
		}
		
		m_nSavedCateID = nCateID;	// 계속 저장 기능을 위해 Category id 를 기억
		
		long ret = m_PrayerDBMngr.insertPrayer(nCateID, m_etPrayer.getText().toString(), m_ckAlarm.isChecked(), strAlarmTime);
		
		if (ret == -1)
		{
			Toast.makeText(PrayerEditActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
			finish();
			bRet = false;
		}
		else
		{
			bRet = true;
		}
		
		return bRet;
	}
	
	/**
	 * Prayer 계속 저장
	 * @return
	 */
	private void saveContinuePrayer()
	{
		// 현재 Prayer 저장
		if (savePrayer())
		{
			Toast.makeText(PrayerEditActivity.this, R.string.prayer_saved, Toast.LENGTH_SHORT).show();
			
			// Category 초기화
			getCategoryName();
			
			// Prayer 창 clear
			m_etPrayer.setText("");
			
			// Alarm 초기화
			m_ckAlarm.setChecked(false);
			setAlarmTimeButton();
		}
	}
	
	/**
	 * Prayer 수정
	 * @return
	 */
	private boolean editPrayer()
	{
		boolean bRet 		 = false;
		int 	nCateID 	 = 0;
		String 	strAlarmTime = "";
		
		// Category ID
		if (m_nSelCategoryIdx == -1)
		{
			// Category 이름 검사
			if (m_etCategory.length() == 0)
			{
				Toast.makeText(PrayerEditActivity.this, R.string.add_category, Toast.LENGTH_SHORT).show();
				m_etCategory.requestFocus();
				return false;
			}
			else
			{
				// 같은 이름의 Category 가 있는지 검사
				nCateID = m_PrayerDBMngr.checkCategoryName(m_etCategory.getText().toString());
				
				if (nCateID == -1)
				{
					// 신규 category 저장
					long lRowID = m_PrayerDBMngr.insertCategory(m_etCategory.getText().toString());
					
					if (lRowID == -1)
					{
						// Error
						Toast.makeText(PrayerEditActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
						finish();
						return false;
					}
					else
					{
						m_nSelCategoryIdx = (int)lRowID;
						nCateID = m_nSelCategoryIdx;
					}
				}
			}
		}
		else
		{
			nCateID = m_mapCategory.get(m_nSelCategoryIdx).getM_nCategoryID();
		}
		
		// Prayer
		if (m_etPrayer.length() == 0)
		{
			Toast.makeText(PrayerEditActivity.this, R.string.add_prayer, Toast.LENGTH_SHORT).show();
			m_etPrayer.requestFocus();
			return false;
		}
		
		// Alarm
		if (m_ckAlarm.isChecked())
		{
			strAlarmTime = m_btnAlarmTime.getText().toString();
		}
		
		long ret = m_PrayerDBMngr.updatePrayer(m_nPrayerID, nCateID, m_etPrayer.getText().toString(), m_ckAlarm.isChecked(), strAlarmTime);
		
		if (ret > 0)
		{
			Toast.makeText(PrayerEditActivity.this, R.string.prayer_updated, Toast.LENGTH_SHORT).show();
			bRet = true;
		}
		else
		{
			Toast.makeText(PrayerEditActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
			bRet = false;
		}
		
		return bRet;
	}
	
	/**
	 * Back 키 이벤트 처리
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			finishActivity();
		}
		
		return false;
	}

}
